package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.SmsCodeGenerator;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.service.ISysMailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.internet.MimeMessage;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 发送邮件验证码服务
 */
@Slf4j
@Service
public class SysMailServiceImpl implements ISysMailService {
    @Autowired
    private RedisService redisService;
    /**
     * 发送邮件验证码间隔
     */
    @Value("${spring.mail.sendinterval}")
    private long sendInterval;

    @Value("${spring.mail.effective_time}")
    private Long effectiveTime;
    @Value("${spring.mail.username}")
    private String mailFrom;
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private TemplateEngine templateEngine;
    @Override
    public void sendMailVerifyCode(String mail) {
        Map<String, Object> result = new HashMap<>();
        //产生四位随机数
        String validateCode = SmsCodeGenerator.generateSmsCode();
        //验证上次发送时间，防止发送过度频繁
       if(!isCanSendSmsCode(mail,validateCode))
           throw new ServiceException("发送验证码过于频繁!");


        //发送邮件
        try {
            Context context = new Context();
            context.setVariable("code", validateCode);
            String htmlContent = templateEngine.process("verification-email", context);

            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setTo(mail);
            helper.setFrom(mailFrom);
            helper.setSubject("您的验证码");
            helper.setText(htmlContent, true); // 第二个参数设置为true表示HTML格式
            mailSender.send(message);

        }catch(Exception e) {
            log.error("发送邮件验证码失败", e);
            throw new ServiceException("发送邮件失败!");
        }
    }

    /**
     * 判断是否能发送邮件验证码
     * @param phoneNumber
     * @param validateCode
     * @return
     */
    public  boolean isCanSendSmsCode(String phoneNumber, String validateCode) {
        // 获取上次发送验证码的时间戳
        String lastRequestTimeStr = redisService.getCacheObject(phoneNumber + ":mail:lastRequest");
        if (lastRequestTimeStr != null) {
            long lastRequestTime = Long.parseLong(lastRequestTimeStr);
            long currentTime = System.currentTimeMillis() / 1000; // 当前时间戳（秒）

            // 检查时间间隔
            if (currentTime - lastRequestTime < sendInterval) {
                return false; // 时间间隔不足，不允许发送
            }
        }

        // 更新时间戳
        redisService.setCacheObject(phoneNumber + ":mail:lastRequest", String.valueOf(System.currentTimeMillis() / 1000), sendInterval, TimeUnit.SECONDS);
        // 记录验证码
        redisService.setCacheObject(phoneNumber + ":mail:code", validateCode, effectiveTime, TimeUnit.MINUTES);
        return true; // 允许发送

    }

    /**
     * 验证码是否正确
     * @param mail 手机号
     * @param code 验证码
     */
    public void verifyCode(String mail,String code) {
        String cacheCode = redisService.getCacheObject(mail + ":mail:code");
        if(!code.equals(cacheCode))
            throw new ServiceException("验证码不正确!");
    }
}
